package com.zhangyj.applets.data;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.io.Writer;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ParamData implements Serializable {

	private static final long serialVersionUID = -702660387174918042L;
	public static final int TYPE_STRING = 0;
	public static final int TYPE_INT = 1;
	public static final int TYPE_DOUBLE = 2;
	public static final int TYPE_FLOAT = 3;
	public static final int TYPE_DATE = 4;
	private Map<String, ParamEntity> params;
	private String actionName;

	public ParamData() {
		params = new HashMap<String, ParamEntity>();
	}

	public void putParam(String key, int type, Object value) {
		params.put(key, new ParamEntity(type, value));
	}

	public void putParam(String key, String value) {
		params.put(key, new ParamEntity(value));
	}

	public Object getParam(String key) {
		return params.get(key).value;
	}

	public String getActionName() {
		return actionName;
	}

	public void setActionName(String actionName) {
		this.actionName = actionName;
	}

	public static class ParamEntity {

		int type;
		Object value;

		public ParamEntity(int type, Object value) {
			this.value = value;
			this.type = type;
		}

		public ParamEntity(String value) {
			this.value = value;
			this.type = TYPE_STRING;
		}
	}

	public void writeTo(Writer writer) throws IOException {
		writer.append("<action>").append(actionName).append("</action>");
		writer.append("<ps>");
		for (Iterator<Map.Entry<String, ParamEntity>> iter = params.entrySet().iterator(); iter.hasNext();) {
			Map.Entry<String, ParamEntity> param = (Map.Entry<String, ParamEntity>) iter.next();

			writer.append("<p n=\"").append(param.getKey()).append("\" t=\"" + param.getValue().type).append("\">")
					.append(param.getValue().type == TYPE_DATE ? (((Date) param.getValue().value).getTime() + "") : param.getValue().value.toString()).append("</p>");
		}
		writer.append("</ps>");
	}

	public static ParamData buildParamData(InputStream in) {
		final ParamData pd = new ParamData();
		DefaultHandler handler = new DefaultHandler() {
			int type = TYPE_STRING;
			boolean isparam = false;
			String paramName = null;

			@Override
			public void characters(char[] data, int offset, int count) throws SAXException {
				String val = String.valueOf(data, offset, count);
				if (isparam == false) {
					pd.actionName = val;
					return;
				}
				switch (type) {
				case TYPE_STRING:
					pd.putParam(paramName, type, val);
					break;
				case TYPE_INT:
					pd.putParam(paramName, type, Integer.valueOf(val));
					break;
				case TYPE_DOUBLE:
					pd.putParam(paramName, type, Double.valueOf(val));
					break;
				case TYPE_FLOAT:
					pd.putParam(paramName, type, Float.valueOf(val));
					break;
				case TYPE_DATE:
					pd.putParam(paramName, type, new Date(Long.valueOf(val)));
					break;
				}
			}

			@Override
			public void startElement(String namespaceURI, String localName, String qName, Attributes attrs) throws SAXException {
				if (qName.equals("p")) {
					isparam = true;
					paramName = attrs.getValue("n");
					type = Integer.parseInt(attrs.getValue("p"));
				}
			}

		};
		SAXParserFactory spf = SAXParserFactory.newInstance();
		SAXParser saxParser;
		try {
			saxParser = spf.newSAXParser();
			saxParser.parse(in, handler);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return pd;
	}
}
